package yz.com.javautil.test;

import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
import java.util.regex.Pattern;


/**
 * <ol>
 * date:2021-01-26 editor:wangzhixiao
 * <li>创建文档</li>
 * <li>热点数据Service实现类</li>
 * </ol>
 *
 * @author <a href="mailto:@qq.com">wangzhixiao</a>
 * @version 1.0
 * @since 1.0
 */

@Component
public class PersonnelLocationManager {
    /**key是手机号、value是归属地编码**/
    private Map<String, String> mobileLocation = new HashMap<String, String>();

    /**key是身份证号（最多前6位，可能是2位、4位、6位），value的四个值按照顺序分别是，归属地、省、市、区，如果市、区不存在则为空字符串**/
    private Map<String, String[]> idcardInfo = new HashMap<String, String[]>();

   /** key是国家编码（IMSI），value的2个值按照顺序是国家名称、国家代码（英文缩写）**/
    private Map<String, String[]> countryCode = new HashMap<String, String[]>();

    private List<String> provinceList = new ArrayList<>();
    /**private List<InfoBean> idcardnuminfoTree = new  ArrayList<>();**/
    /**中国电信中IMSI对照的归属地的行政区划**/
    private Map<String, String> chinaTeleComImsiLocation = new HashMap<>();

    @PostConstruct
    public void init() {
        try {
            mobileLocationReadfiles("mobileLocation.conf", "utf-8");
            readFiles("idcardnuminfo.conf", "utf-8", ",");
            provincelist();
        }catch (Exception e){
            e.printStackTrace();
        }
    }


    private void loadChinaTeleComImsiLocation(String path, String code) throws Exception {
        Resource resource = new ClassPathResource(path);
        InputStreamReader inputStreamReader = new InputStreamReader(resource.getInputStream(), code);

        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        String line = bufferedReader.readLine();
        while (line != null) {
            line = bufferedReader.readLine();
            if (line == null) {
                break;
            }
            String[] fields1 = line.split(",");
            try {
                String[] s = new String[2];
                s[0] = fields1[0].replace(" ", "");
                s[1] = fields1[1].replace(" ", "");
                chinaTeleComImsiLocation.put(s[0], s[1]);
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
        bufferedReader.close();
        inputStreamReader.close();
    }

    private void nationReadfiles(String path, String code) throws IOException {
        Resource resource = new ClassPathResource(path);
        InputStreamReader inputStreamReader = new InputStreamReader(resource.getInputStream(), code);

        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        String line = bufferedReader.readLine();
        while (line != null) {
            String n = line.replace("\"", "");
            String[] fields1 = n.split(",");
            try {
                String[] s = new String[2];
                s[0] = fields1[1].replace(" ", "");
                s[1] = fields1[2].replace(" ", "");
                countryCode.put(fields1[0], s);
            } catch (Exception e) {
                e.printStackTrace();
            }
            line = bufferedReader.readLine();
            if (line == null) {
                break;
            }
        }
        bufferedReader.close();
        inputStreamReader.close();

    }

    private void mobileLocationReadfiles(String path, String code) throws IOException {
        Resource resource = new ClassPathResource(path);
        InputStreamReader inputStreamReader = new InputStreamReader(resource.getInputStream(), code);

        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        String line
                = bufferedReader.readLine();
        while (line != null) {

            String[] fields1 = line.split(",");
            try {

                mobileLocation.put(fields1[0], fields1[1]);
            } catch (Exception e) {
                e.printStackTrace();
            }
            line = bufferedReader.readLine();
            if (line == null) {
                break;
            }
        }
        bufferedReader.close();
        inputStreamReader.close();

    }

    private void readFiles(String path, String code, String regex) throws IOException {
        Resource resource = new ClassPathResource(path);
        InputStreamReader inputStreamReader = new InputStreamReader(resource.getInputStream(), code);

        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        String line = bufferedReader.readLine();
        while (line != null) {
            String[] fields1 = line.split(regex);
            try {
                String[] s = new String[4];
                //在新郑测试后台数组越界,为此添加判断（如逻辑有误,请沟通byCTY）
                if (fields1.length >= 4) {
                    s[0] = fields1[1];
                    s[1] = fields1[2];
                    s[2] = fields1[3];
                    s[3] = fields1[4];
                }
                idcardInfo.put(fields1[0], s);
            } catch (Exception e) {
                e.printStackTrace();
            }
            line = bufferedReader.readLine();
            if (line == null) {
                break;
            }
        }
        bufferedReader.close();
        inputStreamReader.close();
    }

    private String shiftid(String id) {
        if (id.length() == 6) {
            if ("00".equals(id.substring(4, 6))) {
                id = id.substring(0, 4);
                if ("00".equals(id.substring(2, 4))) {
                    id = id.substring(0, 2);
                }
                return id;
            }
        }
        if (id.length() == 4) {
            if ("00".equals(id.substring(2, 4))) {
                id = id.substring(0, 2);
            }
            return id;
        }
        return id;

    }

    private List<String> provincelist() {
        List<String> list = new ArrayList<>();
        for (Map.Entry<String, String[]> p : idcardInfo.entrySet()) {
            if (p.getKey().length() == 2) {
                String[] info = p.getValue();
                list.add(info[1]);
            }
        }
        provinceList = list;
        return list;
    }

//    private void getlocationList(){
//        for(String pro:provinceList){
//            InfoBean cityinfoBean = new InfoBean();
//            Set<String> city = provincecity(pro);
//            List<InfoBean> citylist = new ArrayList<>();
//
//            for(String c:city){
//                InfoBean citinfoBean = new InfoBean();
//                Set<String> qu = cityqu(c);
//                List<InfoBean> qulist = new ArrayList<>();
//                for(String q:qu){
//                    InfoBean quinfoBean = new InfoBean();
//                    quinfoBean.setText(q);
//                    qulist.add(quinfoBean);
//                }
//                citinfoBean.setText(c);
//                citinfoBean.setChild(qulist);
//                citinfoBean.setState("open");
//                citylist.add(citinfoBean);
//            }
//
//            cityinfoBean.setText(pro);
//            cityinfoBean.setChild(citylist);
//            cityinfoBean.setState("open");
//            idcardnuminfoTree.add(cityinfoBean);
//        }
//    }

    /**
     * 中国大陆的imsi转电话号码前7位
     *
     * @param imsiNo
     * @return
     */
    private String convertImsiMobilenum(String imsiNo) {
        String countryCode = imsiNo.substring(0, 3);
        if (!"460".equals(countryCode) && !"461".equals(countryCode) && !"455".equals(countryCode) && !"454".equals(countryCode) && !"466".equals(countryCode)) {
            return null;
        }
        String netWorkId = imsiNo.substring(3, 5);
        String mobileId = imsiNo.substring(5, 10);
        String locationId = "";
        //移动
        if ("00".equalsIgnoreCase(netWorkId)) {
            switch (mobileId.charAt(3)) {
                case '5':
                    locationId = "1350";
                    break;
                case '6':
                    locationId = "1360";
                    break;
                case '7':
                    locationId = "1370";
                    break;
                case '8':
                    locationId = "1380";
                    break;
                case '9':
                    locationId = "1390";
                    break;
                case '0':
                    locationId = "135";
                    locationId += mobileId.charAt(4);
                    break;
                case '1':
                    locationId = "136";
                    locationId += mobileId.charAt(4);
                    break;
                case '2':
                    locationId = "137";
                    locationId += mobileId.charAt(4);
                    break;
                case '3':
                    locationId = "138";
                    locationId += mobileId.charAt(4);
                    break;
                case '4':
                    locationId = "139";
                    locationId += mobileId.charAt(4);
                    break;
                default:
                    return null;
            }
            locationId += mobileId.substring(0, 3);
            //联通
        } else if ("01".equals(netWorkId))
        {
            switch (mobileId.charAt(4)) {
                case '0':
                case '1':
                    locationId = "130";
                    break;
                case '9':
                    locationId = "131";
                    break;
                case '2':
                    locationId = "132";
                    break;
                case '7':
                    locationId = "145";
                    break;
                case '4':
                    locationId = "155";
                    break;
                case '3':
                    locationId = "156";
                    break;
                case '5':
                    locationId = "185";
                    break;
                case '6':
                    locationId = "186";
                    break;
                case '8':
                    locationId = "170";
                    break;
                default:
                    return "ERROR";
            }
            locationId += mobileId.charAt(3);
            locationId += mobileId.substring(0, 3);
        } else if ("02".equals(netWorkId)) {
            switch (mobileId.charAt(0)) {
                case '0':
                    locationId = "134";
                    break;
                case '3':
                    locationId = "150";
                    break;
                case '9':
                    locationId = "159";
                    break;
                case '8':
                    locationId = "158";
                    break;
                case '1':
                    locationId = "151";
                    break;
                case '2':
                    locationId = "152";
                    break;
                case '7':
                    locationId = "187";
                    break;
                case '6':
                    locationId = "182";
                    break;
                case '5':
                    locationId = "183";
                    break;
                case '4':
                    locationId = "184";
                    break;
                default:
                    return null;
            }
            locationId += mobileId.substring(1);
        } else if ("07".equals(netWorkId)) {
            switch (mobileId.charAt(0)) {
                case '7':
                    locationId = "157";
                    break;
                case '8':
                    locationId = "188";
                    break;
                case '9':
                    locationId = "147";
                    break;
                case '5':
                    locationId = "178";
                    break;
                case '0':
                    locationId = "170";
                    break;
                default:
                    return null;
            }
            locationId += mobileId.substring(1);
        }
        return locationId;
    }

    /**
     * 由imsi获取非中国的国家、地区
     *
     * @param imsi
     * @return
     */
    public String getcountry(String imsi) {
        if (imsi.length() < 3) {
            return null;
        }
        String country = imsi.substring(0, 3);
        String[] result = countryCode.get(country);
        if (result == null) {
            return "境外";
        }
        return "境外_" + result[1];
    }

    /**
     * 3.	由城市编码获取归属地
     *
     * @param idcard
     * @return
     */
    public String getlocation(String idcard) {
        idcard = shiftid(idcard);
        String[] r = idcardInfo.get(idcard);
        if (r == null) {
            return null;
        }
        return r[0];
    }

    /**
     * 4.	由归属地获取城市编码
     *
     * @param location
     * @return
     */
    public String getidcard(String location) {
        for (Map.Entry<String, String[]> map : idcardInfo.entrySet()) {
            if (location.equals(map.getValue()[0])) {
                return map.getKey();
            }
        }
        return null;
    }

    /**
     * 5.	由imsi获取归属地名称代码
     *
     * @param imsi
     * @return
     */
    public String getimsilocationCode(String imsi) {
        String mobile = convertImsiMobilenum(imsi);
        String id = mobileLocation.get(mobile);
        if (id == null) {
            return "";
        }
        id = shiftid(id);
        String[] info = idcardInfo.get(id);
        if (info == null) {
            return null;
        }
        return info[0];
    }

    /**
     * 6.	由手机号获取归属地名称
     */
    public String getmobillocation(String mobil) {
        mobil = mobil.substring(0, 7);
        String id = mobileLocation.get(mobil);
        if (id == null) {
            return "";
        }
        id = shiftid(id);
        String[] info = idcardInfo.get(id);
        if (info == null) {
            return null;
        }
        return info[0];
    }

    /**
     * 7.	由imsi获取归属地
     *
     * @param imsi
     * @return
     */
    public String getImsiLocation(String imsi) {
        String countryCode = imsi.substring(0, 3);
        //首先分析非中国大陆、中国香港、中国澳门、中国电信的境外号码的国家名称
        if (!"460".equals(countryCode) && !"461".equals(countryCode)) {
            if ("466".equals(countryCode)) {
                return "中国台湾";
            } else if ("454".equals(countryCode)) {
                return "中国香港";
            } else if ("455".equals(countryCode)) {
                return "中国澳门";
            } else {
                return getcountry(imsi);
            }
        }
        //分析电信中imsi直接对应归属地行政区划的
        String imsiStart = imsi.substring(0, 11);
        String id = null;
        if (chinaTeleComImsiLocation.containsKey(imsiStart)) {
            id = chinaTeleComImsiLocation.get(imsiStart);
        } else {
            String mobil = convertImsiMobilenum(imsi);
            id = mobileLocation.get(mobil);
            if (id == null) {
                return "";
            }
        }

        id = shiftid(id);
        String[] info = idcardInfo.get(id);
        if (info == null) {
            return null;
        }
        return info[0];
    }

    /**
     * 8.	由手机号获取归属地编码
     *
     * @param mobil
     * @return
     */
    public String mobilgetid(String mobil) {
        mobil = mobil.substring(0, 7);
        String id = mobileLocation.get(mobil);
        if (id == null) {
            return "";
        }
        return id;
    }


    /**
     * 9.	由imsi获取运营商
     *
     * @param imsi
     * @return
     */
    public String getImsiOperator(String imsi) {

        String result = "";

        if (imsi.startsWith("460")) {
            String mnc = imsi.substring(3, 5);

            if ("00".equals(mnc) || "02".equals(mnc) || "04".equals(mnc) || "07".equals(mnc)) {

                result = "移动";

            } else if ("01".equals(mnc) || "06".equals(mnc) || "09".equals(mnc) || "20".equals(mnc)) {

                result = "联通";

            } else if ("03".equals(mnc) || "05".equals(mnc) || "11".equals(mnc)) {

                result = "电信";

            }
        }

        return result;

    }

    /**
     * 10.	由手机号获取运营
     *
     * @param phone
     * @return
     */
    public String mobilkOperator(String phone) {

        if (Pattern.matches("(^1(3[4-9]|47|5[0-27-9]|65|78|8[2-478]|98)\\d{8}$)|(^170[356]\\d{7}$)", phone)) {
            return "移动";
        } else if (Pattern.matches("(^1(33|49|53|62|7[37]|8[019]|9[19])\\d{8}$)|(^170[012]\\d{7}$)", phone)) {
            return "电信";
        } else if (Pattern.matches("(^1(3[0-2]|4[05]|5[56]|6[67]|7[156]|8[56])\\d{8}$)|(^170[7-9]\\d{7}$)", phone)) {
            return "联通";
        } else {
            return "error";
        }
    }

    /**
     * 11.	由imsi获取归属地名称加运行商
     *
     * @param imsi
     * @return
     */
    public String imsilocationoper(String imsi) {
        String oper = getImsiOperator(imsi);
        String mobil = convertImsiMobilenum(imsi);
        String id = mobileLocation.get(mobil);
        if (id == null) {
            return "";
        }
        id = shiftid(id);
        String[] info = idcardInfo.get(id);
        if (info == null) {
            return null;
        }
        return info[0] + oper;
    }

    /**
     * 12.	由手机号获取归属地名称加运行商
     *
     * @param mobil
     * @return
     */
    public String mobillocationoper(String mobil) {
        String oper = mobilkOperator(mobil);
        mobil = mobil.substring(0, 7);

        String id = mobileLocation.get(mobil);
        if (id == null) {
            return "";
        }
        id = shiftid(id);
        String[] info = idcardInfo.get(id);
        if (info == null) {
            return null;
        }
        return info[0] + oper;
    }

    /**
     * 13.	判断imsi是否是国外
     *
     * @param imsi
     * @return
     */
    public boolean imsiiscountry(String imsi) {
        String countryCode = imsi.substring(0, 3);
        if ("460".equals(countryCode)) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 15.	由imsi获取国家名称
     *
     * @param imsi
     * @return
     */
    public String imsicountry(String imsi) {
        String country = imsi.substring(0, 3);

        String[] cn = countryCode.get(country);
        if (cn == null) {
            return null;
        }
        return cn[0];
    }

    /**
     * 17.	由imsi获取国家缩写
     *
     * @param imsi
     * @return
     */
    public String imsicountrycode(String imsi) {
        String country = imsi.substring(0, 3);

        String[] cn = countryCode.get(country);
        if (cn == null) {
            return null;
        }
        return cn[1];
    }

    /**
     * 19.	从文本中提取归属地信息
     *
     * @param area
     * @return
     */
    public List<String> arealocation(String area) {
        List<String> provincelist = new ArrayList<String>();
        if (area.length() < 2) {
            return null;
        }
        for (Map.Entry<String, String[]> map : idcardInfo.entrySet()) {
            if (map.getValue()[0].equals(area)) {
                String[] info = map.getValue();
                List<String> result = new ArrayList<>();
                for (int i = 1; i < info.length; i++) {
                    result.add(info[i]);
                }
                return result;
            }
        }
        String newarea = area.substring(0, 2);
        for (Map.Entry<String, String[]> map : idcardInfo.entrySet()) {
            String[] info = map.getValue();
            String pro = info[1].substring(0, 2);
            if (pro.equals(newarea)) {
                provincelist.add(map.getKey());
            }

        }
        Set<String> cityset = new HashSet<>();
        String citycode = null;
        for (String r : provincelist) {
            String[] info = idcardInfo.get(r);
            if (!"".equals(info[2])) {
                String city = info[2].substring(0, 2);
                if (area.contains(city)) {
                    cityset.add(r);
                }
            } else {
                citycode = r;

            }
        }
        if (cityset.size() == 0 && citycode != null) {
            String[] pro = idcardInfo.get(citycode);
            List<String> result = new ArrayList<String>();
            for (int i = 1; i < pro.length; i++) {
                result.add(pro[i]);
            }
            return result;
        }
        List<String> qulist = new ArrayList<String>();
        String qucode = null;
        for (String r : cityset) {
            String[] info = idcardInfo.get(r);
            if (!"".equals(info[3])) {
                String qu = info[3].substring(0, 2);
                if (area.contains(qu)) {
                    qulist.add(r);
                }
            } else {
                qucode = r;
            }
        }
        if (qulist.size() == 0 && qucode != null) {
            String[] pro = idcardInfo.get(qucode);
            List<String> result = new ArrayList<String>();
            for (int i = 1; i < pro.length; i++) {
                result.add(pro[i]);
            }
            return result;
        } else {
            if (qulist.size() != 1) {
                List<String> result = new ArrayList<String>();
                result.add("无法匹配");
                return result;
            } else {
                String code = qulist.get(0);
                String[] pro = idcardInfo.get(code);
                List<String> result = new ArrayList<String>();
                for (int i = 1; i < pro.length; i++) {
                    result.add(pro[i]);
                }
                return result;
            }
        }
    }

    /**
     * 20.	由身份证号获取归属地(可以不是完整的身份证号，根据长度取前2、4、6位进行计算)
     *
     * @param id
     * @return
     */
    public String idlocation(String id) {
        int n = id.length();
        if (n < 6) {
            if (n < 4) {
                if (n < 2) {
                    return "error";
                }
                id = id.substring(0, 2);
                String[] info = idcardInfo.get(id);
                if (info == null) {
                    return "error";
                }
                return info[0];
            } else {
                id = id.substring(0, 4);
                id = shiftid(id);
                String[] info = idcardInfo.get(id);
                if (info == null) {
                    return "error";
                }
                return info[0];
            }
        }
        id = id.substring(0, 6);
        id = shiftid(id);
        String[] info = idcardInfo.get(id);
        if (info == null) {
            return "error";
        }
        return info[0];
    }

    /**
     * 21.	获取省份列表
     */
    public List<String> getprovincelist() {
        return provinceList;
    }


    /**
     * 22.	根据省份或是地市列表
     */
    public Set<String> provincecity(String province) {
        Set<String> list = new HashSet<>();
        for (Map.Entry<String, String[]> p : idcardInfo.entrySet()) {
            String[] info = p.getValue();
            if (province.equals(info[1])) {
                if (!"".equals(info[2])) {
                    list.add(info[2]);
                }

            }
        }
        return list;
    }

    /**
     * 23.	根据地市获取区县列表
     */
    public Set<String> cityqu(String city) {
        Set<String> list = new HashSet<>();
        for (Map.Entry<String, String[]> p : idcardInfo.entrySet()) {
            String[] info = p.getValue();
            if (city.equals(info[2])) {
                if (!"".equals(info[3])) {
                    list.add(info[3]);
                }
            }
        }
        return list;
    }

    /**
     * tree
     *
     * @return
     */

    public static void main(String[] args) {
        PersonnelLocationManager personnelLocationManager = new PersonnelLocationManager();
         System.out.println(personnelLocationManager.getlocation("410800"));



    }


}
